package com.panopset;

import java.awt.Color;
import java.util.ArrayList;
import java.util.List;

/**
 This interface is not intended to be part of any logging or debugging
 mechanism, it is an end user level interface.
 <p/>
 Usage:
 <pre>

 import static com.panopset.Util.*;
 ...
 setDspmsgHandler(&lt;any class that implements DspmsgHandler&gt;)

 dspmsg("Call dspmsg from anywhere");

 </pre>

 For graphic full screen applications, you might want to have a message box
 object that would implement this interface.
 <p/>
 For swing apps, you might want to have a TextField that would implement this
 interface.

 * @author Karl Dinwiddie
 * TODO rename Alert.
 */
public final class Alert {

    /**
     * Green.
     */
    private String info;

    /**
     * Yellow.
     */
    private String warn;

    /**
     * Red.
     */
    private String alrt;

    /**
     * Display message.
     * @param msg Message String to display.
     */
    public static void dspmsg(final String msg) {
        getInstance().info = msg;
        System.out.println(msg);
    }

    /**
     * Display info  message.
     * @param msg Message String to display.
     */
    public static void green(final String msg) {
        dspmsg(msg);
        updt();
    }

    /**
     * Update.
     */
    private static void updt() {
        getInstance().update();
    }

    /**
     * Update.
     */
    private void update() {
        if (al != null) {
            for (UpdateListener ul : getUpdateListeners()) {
                ul.update();
            }
        }
    }
    /**
     * Display warning message.
     * @param msg Message String to display.
     */
    public static void yellow(final String msg) {
        getInstance().warn = msg;
        System.out.println(msg);
        updt();
    }

    /**
     * Display urgent message.
     * @param msg Message String to display.
     */
    public static void red(final String msg) {
        getInstance().alrt = msg;
        System.out.println(msg);
        updt();
    }

    /**
     * Clear warning.
     */
    public static void clearYellow() {
        getInstance().warn = "";
    }

    /**
     * Clear the message display.
     */
    public static void clrmsg() {
        getInstance().alrt = "";
        getInstance().warn = "";
        getInstance().info = "";
    }

    /**
     * @return message.
     */
    public static String getMessage() {
        if (Strings.isPopulated(getInstance().alrt)) {
            return getInstance().alrt;
        } else if (Strings.isPopulated(getInstance().warn)) {
            return getInstance().warn;
        } else if (Strings.isPopulated(getInstance().info)) {
            return getInstance().info;
        }
        return "";
    }

    /**
     * @return Current message color.
     */
    public static Color getColor() {
        if (Strings.isPopulated(getInstance().alrt)) {
            return Color.RED;
        } else if (Strings.isPopulated(getInstance().warn)) {
            return Color.YELLOW;
        }
        return Color.GREEN;
    }


    /**
     * Based on SingletonHolder inner class by Bill Pugh.
     *
     * <h5>References</h5>
     * <ul>
     * <li>
     * <a href="http://en.wikipedia.org/wiki/Singleton_pattern">
     * http://en.wikipedia.org/wiki/Singleton_pattern </a></li>
     * </ul>
     *
     */
    private static final class Singleton {
        /**
         * Instance variable.
         */
        private static final Alert INSTANCE = new Alert();

        /**
         * Private constructor.
         */
        private Singleton() {
            // Prevent instantiation.
        }
    }

    /**
     * Update listeners.
     */
    private List<UpdateListener> al;

    /**
     * @return Update listeners.
     */
    private List<UpdateListener> getUpdateListeners() {
        if (al == null) {
            al = new ArrayList<UpdateListener>();
        }
        return al;
    }

    /**
     * @return static Alert instance.
     */
    protected static Alert getInstance() {
        return Singleton.INSTANCE;
    }

    /**
     * Private singleton constructor.
     */
    private Alert() { }

    /**
     * Add update listener.
     * @param updateListener Update listener.
     */
    public static void addUpdateListener(final UpdateListener updateListener) {
        if (!getInstance().getUpdateListeners().contains(updateListener)) {
            getInstance().getUpdateListeners().add(updateListener);
        }
    }
}
